package com.dongdongshop.aop;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

//aop切面类：在不修改原有代码的基础上，给原有代码做了增强功能，适合统一功能
//日志切面类
@Component  //实例化
@Aspect   //表示当前类是一个切面类
@Slf4j
public class LogAop {

    //切点表达式
    @Pointcut("execution(public * com.dongdongshop.service.*.*(..)) || @annotation(com.dongdongshop.aop.DKLog)")  //切到的位置
    public void log(){}

    //aop的通知: 前置通知、后置通知、环绕通知、异常通知、返回后通知
    //前置通知@Before：在执行之前打印
    //后置通知@After：在进入方法之后打印，但不一定能获取到返回值
    //返回后通知@AfterReturning：在获取返回值之后打印

    //前置通知
    @Before("log()")//指定切点表达式的方法
    public void before(JoinPoint joinPoint){//JoinPoint取参数
        Object[] args = joinPoint.getArgs();//取出所有的参数
        Signature signature = joinPoint.getSignature();//取出当前被切到的方法
        //打印
        log.info("当前被切到的方法为：{}，参数为：{}",signature,args);
    }

    //返回后通知     指定切点表达式的方法    接收的返回值
    @AfterReturning(value = "log()",returning = "result")
    public void afterReturn(Object result){//接收任意类型的返回值
        String s = JSONObject.toJSONString(result);
        log.info("接收到的返回值：{}",s);
    }
}
